import { animation, Component } from "cc";
import { Direction } from "../enums/Direction";
import { eventDispatcher, TILE_HEIGHT, TILE_WIDTH } from "../Constants";
import { AnimatorParam } from "../enums/AnimatorParam";

enum EntityState {
    IDLE = 0,
    BLOCK = 1,
    DEATH = 3,
    ATTACK = 4,
    AIRDEATH = 5,
    TURNLEFT = 6,
    TURNRIGHT = 7
}

enum EntityType {
    PLAYER = 0,
    SKELETON_WOODEN = 1,
    DOOR = 2,
    SMOKE = 3,
    SKELETON_IRON = 4,
    BURST = 5,
    SPIKES = 6
}

const EntityType2Name = {
    [EntityType.PLAYER]: "player",
    [EntityType.SKELETON_WOODEN]: "woodenskeleton",
    [EntityType.DOOR]: "door",
    [EntityType.SMOKE]: "smoke",
    [EntityType.SKELETON_IRON]: "ironskeleton",
    [EntityType.BURST]: "burst",
    [EntityType.SPIKES]: "spikes"
}

export interface IEntity {
    x: number,
    y: number,
    direction?: Direction,
    state: EntityState,
    type: EntityType,
    id?: number,
}

export class Entity extends Component {

    public static ID: number = 0;
    public static readonly State = EntityState;
    public static readonly Type = EntityType;

    public x: number = 0;
    public y: number = 0;
    public id: number = 0;

    protected _type: EntityType;
    protected _animationController: animation.AnimationController;

    protected _direction: Direction = Direction.TOP;
    private _state: EntityState = EntityState.IDLE;

    public get direction(): Direction {
        return this._direction;
    }

    public set direction(value: Direction) {
        this._direction = value;
        if (this._animationController) {
            this._animationController.setValue(AnimatorParam.DIRECTION, value);
        }
    }

    public get state(): EntityState {
        return this._state;
    }

    public set state(value: EntityState) {
        if (this._state !== value) {
            this._state = value;
            if (this._animationController) {
                this._animationController.setValue(AnimatorParam.STATE, value);
            }
        }
    }

    public get type(): EntityType {
        return this._type;
    }

    public get name(): string {
        return EntityType2Name[this.type];
    }

    public getData(): IEntity {
        return {
            x: this.x,
            y: this.y,
            state: this.state,
            direction: this.direction,
            type: this.type,
            id: this.id
        };
    }

    public setData(value: IEntity): void {
        this.x = value.x;
        this.y = value.y;
        this._type = value.type;
        this._animationController.setValue(AnimatorParam.STEP, true);

        

        this.direction = value.direction;
        this.state = value.state;
        this.updatePosition();
    }

    public onLoad(): void {
        this._animationController = this.getComponent(animation.AnimationController);
        this.registerEvents();
    }

    public onDestory(): void {
        eventDispatcher.targetOff(this);
    }

    public init(params: IEntity) {
        this.x = params.x;
        this.y = params.y;
        this.id = Entity.ID++;
        this._type = params.type;
        this._direction = params.direction;
        this._state = params.state;

        this.updatePosition();
    }

    protected registerEvents(): void {

    }

    protected updatePosition(): void {
        this.node.setPosition(this.x * TILE_WIDTH - TILE_WIDTH * 1.5, -this.y * TILE_HEIGHT + TILE_HEIGHT * 1.5);
    }
}
